package com.shop.cereshop.business.redis.listener;

import com.shop.cereshop.business.page.operate.OperateCoupon;
import com.shop.cereshop.business.service.business.CerePlatformBusinessService;
import com.shop.cereshop.business.service.notice.CereNoticeService;
import com.shop.cereshop.business.service.redis.CereRedisKeyServcice;
import com.shop.cereshop.business.service.tool.*;
import com.shop.cereshop.commons.constant.IntegerEnum;
import com.shop.cereshop.commons.constant.StringEnum;
import com.shop.cereshop.commons.domain.business.CerePlatformBusiness;
import com.shop.cereshop.commons.domain.tool.*;
import com.shop.cereshop.commons.exception.CoBusinessException;
import com.shop.cereshop.commons.utils.EmptyUtils;
import com.shop.cereshop.commons.utils.RandomStringUtil;
import com.shop.cereshop.commons.utils.TimeUtils;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.concurrent.TimeUnit;

@Component
public class RedisListener extends KeyExpirationEventMessageListener {

    private RedisTemplate<String, Object> redisTemplate;

    private CerePlatformBusinessService cerePlatformBusinessService;

    private CereRedisKeyServcice cereRedisKeyServcice;

    private CereNoticeService cereNoticeService;

    private CereShopGroupWorkService cereShopGroupWorkService;

    private CereShopSeckillService cereShopSeckillService;

    private CereShopDiscountService cereShopDiscountService;

    private CereShopCouponService cereShopCouponService;

    private CereShopOperateService cereShopOperateService;

    public RedisListener(RedisMessageListenerContainer listenerContainer,
                         RedisTemplate redisTemplate, CerePlatformBusinessService cerePlatformBusinessService
                         , CereRedisKeyServcice cereRedisKeyServcice, CereNoticeService cereNoticeService
                         , CereShopGroupWorkService cereShopGroupWorkService, CereShopSeckillService cereShopSeckillService
                         , CereShopDiscountService cereShopDiscountService, CereShopCouponService cereShopCouponService
                         , CereShopOperateService cereShopOperateService) {
        super(listenerContainer);
        this.redisTemplate=redisTemplate;
        this.cerePlatformBusinessService=cerePlatformBusinessService;
        this.cereRedisKeyServcice=cereRedisKeyServcice;
        this.cereNoticeService=cereNoticeService;
        this.cereShopGroupWorkService=cereShopGroupWorkService;
        this.cereShopSeckillService=cereShopSeckillService;
        this.cereShopDiscountService=cereShopDiscountService;
        this.cereShopCouponService=cereShopCouponService;
        this.cereShopOperateService=cereShopOperateService;
    }

    @Override
    public void onMessage(Message message, byte[] pattern) {
        System.out.println("执行延时任务message:"+message);
        // 用户做自己的业务处理即可,注意message.toString()可以获取失效的key
        String expiredKey = message.toString();
        String time= TimeUtils.yyMMddHHmmss();
        try {
            if(!EmptyUtils.isEmpty(expiredKey)){
                if(expiredKey.contains("-")){
                    String[] split = expiredKey.split("-");
                    String operation=split[0];
                    if(StringEnum.SEVEN_DAY_CHANGE_BUSINESS_TOKEN.getCode().equals(operation)){
                        //替换用户token
                        changeBusinessToken(split[1],time);
                    }else if(StringEnum.NOTICE_OPERATE.getCode().equals(operation)){
                        //运营计划定时发送消息通知
                        //拿到运营计划优惠券数据
                        List<OperateCoupon> coupons = (List<OperateCoupon>) redisTemplate.opsForValue().get(expiredKey);
                        addOperate(split,coupons);
                    }else if(StringEnum.OPERATE_STATE_STOP.getCode().equals(operation)){
                        //修改运营计划状态为进行中
                        updateOperateState(split[1],IntegerEnum.COUPON_STATE_START.getCode());
                    }else if(StringEnum.OPERATE_STATE_STOP.getCode().equals(operation)){
                        //修改运营计划状态为已结束
                        updateOperateState(split[1],IntegerEnum.COUPON_STATE_END.getCode());
                    }else if(StringEnum.SHOP_COUPON_IN.getCode().equals(operation)){
                        //修改店铺优惠券状态为进行中
                        updateShopCouponState(split[1], IntegerEnum.COUPON_STATE_START.getCode(),time);
                    }else if(StringEnum.SHOP_COUPON_END.getCode().equals(operation)){
                        //修改店铺优惠券状态为已结束
                        updateShopCouponState(split[1], IntegerEnum.COUPON_STATE_END.getCode(),time);
                    }else if(StringEnum.SHOP_GROUP_WORK_IN.getCode().equals(operation)){
                        //修改拼团活动状态为进行中
                        updateShopGroupWorkState(split[1],IntegerEnum.COUPON_STATE_START.getCode(),time);
                    }else if(StringEnum.SHOP_GROUP_WORK_END.getCode().equals(operation)){
                        //修改拼团活动状态为已结束
                        updateShopGroupWorkState(split[1],IntegerEnum.COUPON_STATE_END.getCode(),time);
                    }else if(StringEnum.SHOP_SECKILL_IN.getCode().equals(operation)){
                        //修改秒杀活动状态为进行中
                        updateShopSeckillState(split[1],IntegerEnum.COUPON_STATE_START.getCode(),time);
                    }else if(StringEnum.SHOP_SECKILL_END.getCode().equals(operation)){
                        //修改秒杀活动状态为已结束
                        updateShopSeckillState(split[1],IntegerEnum.COUPON_STATE_END.getCode(),time);
                    }else if(StringEnum.SHOP_DISCOUNT_IN.getCode().equals(operation)){
                        //修改限时折扣活动状态为进行中
                        updateShopDiscountState(split[1],IntegerEnum.COUPON_STATE_START.getCode(),time);
                    }else if(StringEnum.SHOP_DISCOUNT_END.getCode().equals(operation)){
                        //修改限时折扣活动状态为已结束
                        updateShopDiscountState(split[1],IntegerEnum.COUPON_STATE_END.getCode(),time);
                    }
                    //删除失效的key
                    redisTemplate.delete(expiredKey);
                    //删除redis延时任务记录
                    cereRedisKeyServcice.deleteByKey(expiredKey);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    private void updateOperateState(String shopOperateId, Integer state) throws CoBusinessException,Exception{
        String time =TimeUtils.yyMMddHHmmss();
        CereShopOperate cereShopOperate=cereShopOperateService.findById(Long.parseLong(shopOperateId));
        if(cereShopOperate!=null){
            cereShopOperate.setState(state);
            cereShopOperate.setUpdateTime(time);
            cereShopOperateService.updateState(cereShopOperate);
            if(IntegerEnum.COUPON_STATE_START.getCode().equals(state)){
                //如果当前是修改状态为进行中,新增延时任务修改状态为已结束
                //新增延时任务修改状态为已结束
                redisTemplate.opsForValue().set(StringEnum.OPERATE_STATE_STOP.getCode()+"-"+shopOperateId,1,
                        TimeUtils.getCountDownByTime(time,cereShopOperate.getPlanEnd()), TimeUnit.MILLISECONDS);
                //新增延时记录
                cereRedisKeyServcice.add(StringEnum.OPERATE_STATE_STOP.getCode()+"-"+shopOperateId,cereShopOperate.getPlanEnd());
            }
        }
    }

    private void updateShopDiscountState(String id, Integer state, String time) throws CoBusinessException,Exception{
        Long shopDiscountId = Long.parseLong(id);
        //查询限时折扣活动数据
        CereShopDiscount cereShopDiscount=cereShopDiscountService.findById(shopDiscountId);
        if(cereShopDiscount!=null){
            cereShopDiscount.setState(state);
            cereShopDiscount.setUpdateTime(time);
            //更新限时折扣活动状态
            cereShopDiscountService.updateState(cereShopDiscount);
            if(IntegerEnum.COUPON_STATE_START.getCode().equals(state)){
                //如果当前修改状态为进行中,修改之后新增延时任务修改状态为已结束
                redisTemplate.opsForValue().set(StringEnum.SHOP_DISCOUNT_END.getCode()+"-"+cereShopDiscount.getShopDiscountId(),1,
                        TimeUtils.getCountDownByTime(time,cereShopDiscount.getEndTime()), TimeUnit.MILLISECONDS);
                //新增延时记录
                cereRedisKeyServcice.add(StringEnum.SHOP_DISCOUNT_END.getCode()+"-"+cereShopDiscount.getShopDiscountId(),cereShopDiscount.getEndTime());
            }
        }
    }

    private void updateShopSeckillState(String id, Integer state,String time) throws CoBusinessException,Exception{
        Long shopSeckillId = Long.parseLong(id);
        //查询秒杀活动数据
        CereShopSeckill cereShopSeckill=cereShopSeckillService.findById(shopSeckillId);
        if(cereShopSeckill!=null){
            cereShopSeckill.setState(state);
            cereShopSeckill.setUpdateTime(time);
            //更新秒杀活动状态
            cereShopSeckillService.updateState(cereShopSeckill);
            if(IntegerEnum.COUPON_STATE_START.getCode().equals(state)){
                //如果当前修改状态为进行中,修改之后新增延时任务修改状态为已结束
                redisTemplate.opsForValue().set(StringEnum.SHOP_SECKILL_END.getCode()+"-"+cereShopSeckill.getShopSeckillId(),1,
                        TimeUtils.getCountDownByTime(time,cereShopSeckill.getEffectiveEnd()), TimeUnit.MILLISECONDS);
                //新增延时记录
                cereRedisKeyServcice.add(StringEnum.SHOP_SECKILL_END.getCode()+"-"+cereShopSeckill.getShopSeckillId(),cereShopSeckill.getEffectiveEnd());
            }
        }
    }

    private void updateShopGroupWorkState(String id, Integer state,String time) throws CoBusinessException,Exception{
        Long shopGroupWorkId = Long.parseLong(id);
        //查询拼团活动数据
        CereShopGroupWork cereShopGroupWork=cereShopGroupWorkService.findById(shopGroupWorkId);
        if(cereShopGroupWork!=null){
            cereShopGroupWork.setState(state);
            cereShopGroupWork.setUpdateTime(time);
            //更新拼团活动状态
            cereShopGroupWorkService.updateState(cereShopGroupWork);
            if(IntegerEnum.COUPON_STATE_START.getCode().equals(state)){
                //如果当前修改状态为进行中,修改之后新增延时任务修改状态为已结束
                redisTemplate.opsForValue().set(StringEnum.SHOP_GROUP_WORK_END.getCode()+"-"+cereShopGroupWork.getShopGroupWorkId(),1,
                        TimeUtils.getCountDownByTime(time,cereShopGroupWork.getEndTime()), TimeUnit.MILLISECONDS);
                //新增延时记录
                cereRedisKeyServcice.add(StringEnum.SHOP_GROUP_WORK_END.getCode()+"-"+cereShopGroupWork.getShopGroupWorkId(),cereShopGroupWork.getEndTime());
            }
        }
    }

    private void updateShopCouponState(String id, Integer state,String time) throws CoBusinessException,Exception{
        Long shopCouponId = Long.parseLong(id);
        //查询店铺优惠券数据
        CereShopCoupon cereShopCoupon=cereShopCouponService.findById(shopCouponId);
        if(cereShopCoupon!=null){
            cereShopCoupon.setState(state);
            cereShopCoupon.setUpdateTime(time);
            //更新店铺优惠券状态
            cereShopCouponService.updateState(cereShopCoupon);
            if(IntegerEnum.COUPON_STATE_START.getCode().equals(state)){
                //如果当前修改状态为进行中,修改之后新增延时任务修改状态为已结束
                redisTemplate.opsForValue().set(StringEnum.SHOP_COUPON_END.getCode()+"-"+cereShopCoupon.getShopCouponId(),1,
                        TimeUtils.getCountDownByTime(time,cereShopCoupon.getEffectiveEnd()), TimeUnit.MILLISECONDS);
                //新增延时记录
                cereRedisKeyServcice.add(StringEnum.SHOP_COUPON_END.getCode()+"-"+cereShopCoupon.getShopCouponId(),cereShopCoupon.getEffectiveEnd());
            }else {
                //如果当前修改状态为已结束,需要同步修改客户领取该优惠券状态为已过期
                cereShopCouponService.updateBuyerCouponState(cereShopCoupon.getShopCouponId());
            }
        }
    }

    private void addOperate(String[] split,List<OperateCoupon> coupons) throws CoBusinessException{
        Long shopOperateId=Long.parseLong(split[1]);
        Long shopCrowdId=Long.parseLong(split[2]);
        Long shopId=Long.parseLong(split[3]);
        //性钙运营计划状态为已结束
        CereShopOperate cereShopOperate=new CereShopOperate();
        cereShopOperate.setUpdateTime(TimeUtils.yyMMddHHmmss());
        cereShopOperate.setState(IntegerEnum.COUPON_STATE_END.getCode());
        cereShopOperate.setShopOperateId(shopOperateId);
        cereShopOperateService.updateState(cereShopOperate);
        cereNoticeService.addOperate(shopCrowdId,coupons,shopId,shopOperateId);
    }

    private void changeBusinessToken(String businessUserId, String time) throws CoBusinessException{
        CerePlatformBusiness cerePlatformBusiness=new CerePlatformBusiness();
        cerePlatformBusiness.setBusinessUserId(Long.parseLong(businessUserId));
        cerePlatformBusiness.setUpdateTime(time);
        cerePlatformBusiness.setToken(RandomStringUtil.getRandomCode(128,0));
        cerePlatformBusinessService.updateToken(cerePlatformBusiness);
    }
}
